/*
 * This file is part of Ext JS 3.4 Copyright (c) 2011-2013 Sencha Inc Contact: http://www.sencha.com/contact GNU General Public License Usage This file may be
 * used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in
 * the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met:
 * http://www.gnu.org/copyleft/gpl.html. If you are unsure which license is appropriate for your use, please contact the sales department at
 * http://www.sencha.com/contact. Build date: 2013-04-03 15:07:25
 */
// for old browsers
window.undefined = window.undefined;

/**
 * @class Ext Ext core utilities and functions.
 * @singleton
 */

Ext =
{
	/**
	 * The version of the framework
	 * 
	 * @type String
	 */
	version: '3.4.1.1',
	versionDetail:
	{
		major: 3,
		minor: 4,
		patch: 1.1
	}
};

/**
 * Copies all the properties of config to obj.
 * 
 * @param {Object} obj The receiver of the properties
 * @param {Object} config The source of the properties
 * @param {Object} defaults A different object that will also be applied for default values
 * @return {Object} returns obj
 * @member Ext apply
 */
Ext.apply = function( o, c, defaults )
{
	// no "this" reference for friendly out of scope calls
	if( defaults )
	{
		Ext.apply(o, defaults);
	}
	if( o && c && typeof c == 'object' )
	{
		for( var p in c )
		{
			o[p] = c[p];
		}
	}
	return o;
};

(function()
{
	var idSeed = 0, toString = Object.prototype.toString, ua = navigator.userAgent.toLowerCase(), check = function( r )
	{
		return r.test(ua);
	}, DOC = document, docMode = DOC.documentMode, isStrict = DOC.compatMode == "CSS1Compat", isOpera = check(/opera/), isChrome = check(/\bchrome\b/), isWebKit = check(/webkit/), isSafari = !isChrome && check(/safari/), isSafari2 =
	isSafari && check(/applewebkit\/4/), // unique to Safari 2
	isSafari3 = isSafari && check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), isIE = !isOpera && check(/msie/), isIE7 = isIE && ((check(/msie 7/) && docMode != 8 && docMode != 9 && docMode != 10) || docMode == 7), isIE8 =
	isIE && ((check(/msie 8/) && docMode != 7 && docMode != 9 && docMode != 10) || docMode == 8), isIE9 = isIE && ((check(/msie 9/) && docMode != 7 && docMode != 8 && docMode != 10) || docMode == 9), isIE10 =
	isIE && ((check(/msie 10/) && docMode != 7 && docMode != 8 && docMode != 9) || docMode == 10), isIE6 = isIE && check(/msie 6/), isIE9m = isIE && (isIE6 || isIE7 || isIE8 || isIE9), isGecko = !isWebKit && check(/gecko/), isGecko2 =
	isGecko && check(/rv:1\.8/), isGecko3 = isGecko && check(/rv:1\.9/), isBorderBox = isIE9m && !isStrict, isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isAir = check(/adobeair/), isLinux = check(/linux/), isSecure =
	/^https/i.test(window.location.protocol), noArgs = [], nonEnumerables = [], emptyFn = Ext.emptyFn, t = Ext.apply({},
	{
		constructor: emptyFn,
		toString: emptyFn,
		valueOf: emptyFn
	}), callOverrideParent = function()
	{
		var method = callOverrideParent.caller.caller; // skip callParent (our caller)
		return method.$owner.prototype[method.$name].apply(this, arguments);
	};

	if( t.constructor !== emptyFn )
	{
		nonEnumerables.push('constructor');
	}
	if( t.toString !== emptyFn )
	{
		nonEnumerables.push('toString');
	}
	if( t.valueOf !== emptyFn )
	{
		nonEnumerables.push('valueOf');
	}
	if( !nonEnumerables.length )
	{
		nonEnumerables = null;
	}

	// Create the abstract Base class to provide an empty constructor and callParent implementations
	function Base()
	{
		//
	}

	Ext.apply(Base,
	{
		$isClass: true,

		callParent: function( args )
		{
			var method;

			// This code is intentionally inlined for the least number of debugger stepping
			return (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass.self[method.$name])).apply(this, args || noArgs);
		}
	});

	Base.prototype =
	{
		constructor: function()
		{
		},
		callParent: function( args )
		{
			// NOTE: this code is deliberately as few expressions (and no function calls)
			// as possible so that a debugger can skip over this noise with the minimum number
			// of steps. Basically, just hit Step Into until you are where you really wanted
			// to be.
			var method, superMethod = (method = this.callParent.caller) && (method.$previous || ((method = method.$owner ? method : method.caller) && method.$owner.superclass[method.$name]));

			return superMethod.apply(this, args || noArgs);
		}
	};

	// remove css image flicker
	if( isIE6 )
	{
		try
		{
			DOC.execCommand("BackgroundImageCache", false, true);
		}
		catch (e)
		{
		}
	}

	Ext.apply(Ext,
	{
		/**
		 * URL to a blank file used by Ext when in secure mode for iframe src and onReady src to prevent the IE insecure content warning (<tt>'about:blank'</tt>,
		 * except for IE in secure mode, which is <tt>'javascript:""'</tt>).
		 * 
		 * @type String
		 */
		SSL_SECURE_URL: isSecure && isIE ? 'javascript:""' : 'about:blank',
		/**
		 * True if the browser is in strict (standards-compliant) mode, as opposed to quirks mode
		 * 
		 * @type Boolean
		 */
		isStrict: isStrict,
		/**
		 * True if the page is running over SSL
		 * 
		 * @type Boolean
		 */
		isSecure: isSecure,
		/**
		 * True when the document is fully initialized and ready for action
		 * 
		 * @type Boolean
		 */
		isReady: false,

		/**
		 * True if the {@link Ext.Fx} Class is available
		 * 
		 * @type Boolean
		 * @property enableFx
		 */

		/**
		 * HIGHLY EXPERIMENTAL True to force css based border-box model override and turning off javascript based adjustments. This is a runtime configuration and
		 * must be set before onReady.
		 * 
		 * @type Boolean
		 */
		enableForcedBoxModel: false,

		/**
		 * True to automatically uncache orphaned Ext.Elements periodically (defaults to true)
		 * 
		 * @type Boolean
		 */
		enableGarbageCollector: true,

		/**
		 * True to automatically purge event listeners during garbageCollection (defaults to false).
		 * 
		 * @type Boolean
		 */
		enableListenerCollection: false,

		/**
		 * EXPERIMENTAL - True to cascade listener removal to child elements when an element is removed. Currently not optimized for performance.
		 * 
		 * @type Boolean
		 */
		enableNestedListenerRemoval: false,

		/**
		 * Indicates whether to use native browser parsing for JSON methods. This option is ignored if the browser does not support native JSON methods. <b>Note:
		 * Native JSON methods will not work with objects that have functions. Also, property names must be quoted, otherwise the data will not parse.</b>
		 * (Defaults to false)
		 * 
		 * @type Boolean
		 */
		USE_NATIVE_JSON: false,

		/**
		 * Copies all the properties of config to obj if they don't already exist.
		 * 
		 * @param {Object} obj The receiver of the properties
		 * @param {Object} config The source of the properties
		 * @return {Object} returns obj
		 */
		applyIf: function( o, c )
		{
			if( o )
			{
				for( var p in c )
				{
					if( !Ext.isDefined(o[p]) )
					{
						o[p] = c[p];
					}
				}
			}
			return o;
		},

		/**
		 * Generates unique ids. If the element already has an id, it is unchanged
		 * 
		 * @param {Mixed} el (optional) The element to generate an id for
		 * @param {String} prefix (optional) Id prefix (defaults "ext-gen")
		 * @return {String} The generated Id.
		 */
		id: function( el, prefix )
		{
			el = Ext.getDom(el, true) || {};
			if( !el.id )
			{
				el.id = (prefix || "ext-gen") + (++idSeed);
			}
			return el.id;
		},

		/**
		 * <p>Extends one class to create a subclass and optionally overrides members with the passed literal. This method also adds the function "override()" to
		 * the subclass that can be used to override members of the class.</p> For example, to create a subclass of Ext GridPanel:
		 * 
		 * <pre><code>
		 * 		MyGridPanel = Ext.extend(Ext.grid.GridPanel, {
		 * 		constructor: function(config) {
		 * 
		 * 		//      Create configuration for this Grid.
		 * 		var store = new Ext.data.Store({...});
		 * 		var colModel = new Ext.grid.ColumnModel({...});
		 * 
		 * 		//      Create a new config object containing our computed properties
		 * 		//      *plus* whatever was in the config parameter.
		 * 		config = Ext.apply({
		 * 		    store: store,
		 * 		    colModel: colModel
		 * 		}, config);
		 * 
		 * 		MyGridPanel.superclass.constructor.call(this, config);
		 * 
		 * 		//      Your postprocessing here
		 * 		},
		 * 
		 * 		yourMethod: function() {
		 * 		// etc.
		 * 		}
		 * 		});
		 * 		
		 * </code></pre>
		 * 
		 * <p>This function also supports a 3-argument call in which the subclass's constructor is passed as an argument. In this form, the parameters are as
		 * follows:</p> <div class="mdetail-params"><ul> <li><code>subclass</code> : Function <div class="sub-desc">The subclass constructor.</div></li> <li><code>superclass</code> :
		 * Function <div class="sub-desc">The constructor of class being extended</div></li> <li><code>overrides</code> : Object <div class="sub-desc">A
		 * literal with members which are copied into the subclass's prototype, and are therefore shared among all instances of the new class.</div></li> </ul></div>
		 * 
		 * @param {Function} superclass The constructor of class being extended.
		 * @param {Object} overrides <p>A literal with members which are copied into the subclass's prototype, and are therefore shared between all instances of
		 *        the new class.</p> <p>This may contain a special member named <tt><b>constructor</b></tt>. This is used to define the constructor of the new
		 *        class, and is returned. If this property is <i>not</i> specified, a constructor is generated and returned which just calls the superclass's
		 *        constructor passing on its parameters.</p> <p><b>It is essential that you call the superclass constructor in any provided constructor. See
		 *        example code.</b></p>
		 * @return {Function} The subclass constructor from the <code>overrides</code> parameter, or a generated one if not provided.
		 */
		extend: function()
		{
			// inline overrides
			var io = function( o )
			{
				for( var m in o )
				{
					this[m] = o[m];
				}
			};
			var oc = Object.prototype.constructor;

			return function( sb, sp, overrides )
			{
				if( typeof sp == 'object' )
				{
					overrides = sp;
					sp = sb;
					sb = overrides.constructor != oc ? overrides.constructor : function()
					{
						sp.apply(this, arguments);
					};
				}
				var F = function()
				{
				}, sbp, spp = sp.prototype;

				F.prototype = spp;
				sbp = sb.prototype = new F();
				sbp.constructor = sb;
				sb.superclass = spp;
				if( spp.constructor == oc )
				{
					spp.constructor = sp;
				}
				sb.override = function( o )
				{
					Ext.override(sb, o);
				};
				sbp.superclass = sbp.supr = (function()
				{
					return spp;
				});
				sbp.override = io;
				Ext.override(sb, overrides);
				sb.extend = function( o )
				{
					return Ext.extend(sb, o);
				};
				return sb;
			};
		}(),

		global: (function()
		{
			return this;
		})(),

		Base: Base,

		namespaceCache: {},

		createNamespace: function( namespaceOrClass, isClass )
		{
			var cache = Ext.namespaceCache, namespace = isClass ? namespaceOrClass.substring(0, namespaceOrClass.lastIndexOf('.')) : namespaceOrClass, ns = cache[namespace], i, n, part, parts, partials;

			if( !ns )
			{
				ns = Ext.global;
				if( namespace )
				{
					partials = [];
					parts = namespace.split('.');

					for( i = 0, n = parts.length; i < n; ++i )
					{
						part = parts[i];

						ns = ns[part] || (ns[part] = {});
						partials.push(part);

						cache[partials.join('.')] = ns; // build up prefixes as we go
					}
				}
			}

			return ns;
		},

		getClassByName: function( className )
		{
			var parts = className.split('.'), cls = Ext.global, n = parts.length, i;

			for( i = 0; cls && i < n; ++i )
			{
				cls = cls[parts[i]];
			}

			return cls || null;
		},

		addMembers: function( cls, target, members, handleNonEnumerables )
		{
			var i, name, member;

			for( name in members )
			{
				if( members.hasOwnProperty(name) )
				{
					member = members[name];
					if( typeof member == 'function' )
					{
						member.$owner = cls;
						member.$name = name;
					}

					target[name] = member;
				}
			}

			if( handleNonEnumerables && nonEnumerables )
			{
				for( i = nonEnumerables.length; i-- > 0; )
				{
					name = nonEnumerables[i];
					if( members.hasOwnProperty(name) )
					{
						member = members[name];
						if( typeof member == 'function' )
						{
							member.$owner = cls;
							member.$name = name;
						}

						target[name] = member;
					}
				}
			}
		},

		/**
		 * @method Defines a class or override. A basic class is defined like this: Ext.define('My.awesome.Class', { someProperty: 'something', someMethod:
		 *         function(s) { alert(s + this.someProperty); } ... }); var obj = new My.awesome.Class(); obj.someMethod('Say '); // alerts 'Say something' To
		 *         create an anonymous class, pass `null` for the `className`: Ext.define(null, { constructor: function () { // ... } }); In some cases, it is
		 *         helpful to create a nested scope to contain some private properties. The best way to do this is to pass a function instead of an object as the
		 *         second parameter. This function will be called to produce the class body: Ext.define('MyApp.foo.Bar', function () { var id = 0; return { nextId:
		 *         function () { return ++id; } }; }); When using this form of `Ext.define`, the function is passed a reference to its class. This can be used as an
		 *         efficient way to access any static properties you may have: Ext.define('MyApp.foo.Bar', function (Bar) { return { statics: { staticMethod:
		 *         function () { // ... } }, method: function () { return Bar.staticMethod(); } }; }); To define an override, include the `override` property. The
		 *         content of an override is aggregated with the specified class in order to extend or modify that class. This can be as simple as setting default
		 *         property values or it can extend and/or replace methods. This can also extend the statics of the class. One use for an override is to break a
		 *         large class into manageable pieces. // File: /src/app/Panel.js Ext.define('My.app.Panel', { extend: 'Ext.panel.Panel', constructor: function
		 *         (config) { this.callParent(arguments); // calls Ext.panel.Panel's constructor //... }, statics: { method: function () { return 'abc'; } } }); //
		 *         File: /src/app/PanelPart2.js Ext.define('My.app.PanelPart2', { override: 'My.app.Panel', constructor: function (config) {
		 *         this.callParent(arguments); // calls My.app.Panel's constructor //... } }); Another use of overrides is to provide optional parts of classes that
		 *         can be independently required. In this case, the class may even be unaware of the override altogether. Ext.define('My.ux.CoolTip', { override:
		 *         'Ext.tip.ToolTip', constructor: function (config) { this.callParent(arguments); // calls Ext.tip.ToolTip's constructor //... } }); Overrides can
		 *         also contain statics: Ext.define('My.app.BarMod', { override: 'Ext.foo.Bar', statics: { method: function (x) { return this.callParent([x * 2]); //
		 *         call Ext.foo.Bar.method } } });
		 * @param {String} className The class name to create in string dot-namespaced format, for example: 'My.very.awesome.Class', 'FeedViewer.plugin.CoolPager'
		 *        It is highly recommended to follow this simple convention: - The root and the class name are 'CamelCased' - Everything else is lower-cased Pass
		 *        `null` to create an anonymous class.
		 * @param {Object} data The key - value pairs of properties to apply to this class. Property names can be of any valid strings, except those in the reserved
		 *        listed below: - `mixins` - `statics` - `config` - `alias` - `self` - `singleton` - `alternateClassName` - `override`
		 * @param {Function} createdFn Optional callback to execute after the class is created, the execution scope of which (`this`) will be the newly created
		 *        class itself.
		 * @return {Ext.Base}
		 * @markdown
		 * @member Ext
		 * @method define
		 */
		define: function( className, body, createdFn )
		{
			var override = body.override, cls, extend, name, namespace;

			if( override )
			{
				delete body.override;
				cls = Ext.getClassByName(override);
				Ext.override(cls, body);
			}
			else
			{
				if( className )
				{
					namespace = Ext.createNamespace(className, true);
					name = className.substring(className.lastIndexOf('.') + 1);
				}

				cls = function ctor()
				{
					this.constructor.apply(this, arguments);
				}

				if( className )
				{
					cls.displayName = className;
				}
				cls.$isClass = true;
				cls.callParent = Ext.Base.callParent;

				if( typeof body == 'function' )
				{
					body = body(cls);
				}

				extend = body.extend;
				if( extend )
				{
					delete body.extend;
					if( typeof extend == 'string' )
					{
						extend = Ext.getClassByName(extend);
					}
				}
				else
				{
					extend = Base;
				}

				Ext.extend(cls, extend, body);
				if( cls.prototype.constructor === cls )
				{
					delete cls.prototype.constructor;
				}

				// Not extending a class which derives from Base...
				if( !cls.prototype.$isClass )
				{
					Ext.applyIf(cls.prototype, Base.prototype);
				}
				cls.prototype.self = cls;

				if( body.xtype )
				{
					Ext.reg(body.xtype, cls);
				}
				cls = body.singleton ? new cls() : cls;
				if( className )
				{
					namespace[name] = cls;
				}
			}

			if( createdFn )
			{
				createdFn.call(cls);
			}

			return cls;
		},

		/**
		 * Overrides members of the specified `target` with the given values. If the `target` is a function, it is assumed to be a constructor and the contents of
		 * `overrides` are applied to its `prototype` using {@link Ext#apply Ext.apply}. If the `target` is an instance of a class created using {@link #define},
		 * the `overrides` are applied to only that instance. In this case, methods are specially processed to allow them to use {@link Ext.Base#callParent}. var
		 * panel = new Ext.Panel({ ... }); Ext.override(panel, { initComponent: function () { // extra processing... this.callParent(); } }); If the `target` is
		 * none of these, the `overrides` are applied to the `target` using {@link Ext#apply Ext.apply}. Please refer to {@link Ext#define Ext.define} for further
		 * details.
		 * 
		 * @param {Object} target The target to override.
		 * @param {Object} overrides The properties to add or replace on `target`.
		 * @method override
		 */
		override: function( target, overrides )
		{
			var proto, statics;

			if( overrides )
			{
				if( target.$isClass )
				{
					statics = overrides.statics;
					if( statics )
					{
						delete overrides.statics;
					}

					Ext.addMembers(target, target.prototype, overrides, true);
					if( statics )
					{
						Ext.addMembers(target, target, statics);
					}
				}
				else if( typeof target == 'function' )
				{
					proto = target.prototype;
					Ext.apply(proto, overrides);
					if( Ext.isIE && overrides.hasOwnProperty('toString') )
					{
						proto.toString = overrides.toString;
					}
				}
				else
				{
					var owner = target.self, name, value;

					if( owner && owner.$isClass )
					{
						for( name in overrides )
						{
							if( overrides.hasOwnProperty(name) )
							{
								value = overrides[name];

								if( typeof value == 'function' )
								{
									// <debug>
									if( owner.$className )
									{
										value.displayName = owner.$className + '#' + name;
									}
									// </debug>

									value.$name = name;
									value.$owner = owner;
									value.$previous = target.hasOwnProperty(name) ? target[name] // already hooked, so call previous hook
									: callOverrideParent; // calls by name on prototype
								}

								target[name] = value;
							}
						}
					}
					else
					{
						Ext.apply(target, overrides);

						if( !target.constructor.$isClass )
						{
							target.constructor.prototype.callParent = Base.prototype.callParent;
							target.constructor.callParent = Base.callParent;
						}
					}
				}
			}
		},

		/**
		 * Creates namespaces to be used for scoping variables and classes so that they are not global. Specifying the last node of a namespace implicitly creates
		 * all other nodes. Usage:
		 * 
		 * <pre><code>
		 * 		Ext.namespace('Company', 'Company.data');
		 * 		Ext.namespace('Company.data'); // equivalent and preferable to above syntax
		 * 		Company.Widget = function() { ... }
		 * 		Company.data.CustomStore = function(config) { ... }
		 * 		
		 * </code></pre>
		 * 
		 * @param {String} namespace1
		 * @param {String} namespace2
		 * @param {String} etc
		 * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
		 * @method namespace
		 */
		namespace: function()
		{
			var len1 = arguments.length, i = 0, len2, j, main, ns, sub, current;

			for( ; i < len1; ++i )
			{
				main = arguments[i];
				ns = arguments[i].split('.');
				current = window[ns[0]];
				if( current === undefined )
				{
					current = window[ns[0]] = {};
				}
				sub = ns.slice(1);
				len2 = sub.length;
				for( j = 0; j < len2; ++j )
				{
					current = current[sub[j]] = current[sub[j]] || {};
				}
			}
			return current;
		},

		/**
		 * Takes an object and converts it to an encoded URL. e.g. Ext.urlEncode({foo: 1, bar: 2}); would return "foo=1&bar=2". Optionally, property values can be
		 * arrays, instead of keys and the resulting string that's returned will contain a name/value pair for each array value.
		 * 
		 * @param {Object} o
		 * @param {String} pre (optional) A prefix to add to the url encoded string
		 * @return {String}
		 */
		urlEncode: function( o, pre )
		{
			var empty, buf = [], e = encodeURIComponent;

			Ext.iterate(o, function( key, item )
			{
				empty = Ext.isEmpty(item);
				Ext.each(empty ? key : item, function( val )
				{
					buf.push('&', e(key), '=', (!Ext.isEmpty(val) && (val != key || !empty)) ? (Ext.isDate(val) ? Ext.encode(val).replace(/"/g, '') : e(val)) : '');
				});
			});
			if( !pre )
			{
				buf.shift();
				pre = '';
			}
			return pre + buf.join('');
		},

		/**
		 * Takes an encoded URL and and converts it to an object. Example:
		 * 
		 * <pre><code>
		 * Ext.urlDecode(&quot;foo=1&amp;bar=2&quot;); // returns {foo: &quot;1&quot;, bar: &quot;2&quot;}
		 * Ext.urlDecode(&quot;foo=1&amp;bar=2&amp;bar=3&amp;bar=4&quot;, false); // returns {foo: &quot;1&quot;, bar: [&quot;2&quot;, &quot;3&quot;, &quot;4&quot;]}
		 * </code></pre>
		 * 
		 * @param {String} string
		 * @param {Boolean} overwrite (optional) Items of the same name will overwrite previous values instead of creating an an array (Defaults to false).
		 * @return {Object} A literal with members
		 */
		urlDecode: function( string, overwrite )
		{
			if( Ext.isEmpty(string) )
			{
				return {};
			}
			var obj = {}, pairs = string.split('&'), d = decodeURIComponent, name, value;
			Ext.each(pairs, function( pair )
			{
				pair = pair.split('=');
				name = d(pair[0]);
				value = d(pair[1]);
				obj[name] = overwrite || !obj[name] ? value : [].concat(obj[name]).concat(value);
			});
			return obj;
		},

		/**
		 * Appends content to the query string of a URL, handling logic for whether to place a question mark or ampersand.
		 * 
		 * @param {String} url The URL to append to.
		 * @param {String} s The content to append to the URL.
		 * @return (String) The resulting URL
		 */
		urlAppend: function( url, s )
		{
			if( !Ext.isEmpty(s) )
			{
				return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
			}
			return url;
		},

		/**
		 * Converts any iterable (numeric indices and a length property) into a true array Don't use this on strings. IE doesn't support "abc"[0] which this
		 * implementation depends on. For strings, use this instead: "abc".match(/./g) => [a,b,c];
		 * 
		 * @param {Iterable} the iterable object to be turned into a true Array.
		 * @return (Array) array
		 */
		toArray: function()
		{
			return isIE ? function( a, i, j, res )
			{
				res = [];
				for( var x = 0, len = a.length; x < len; x++ )
				{
					res.push(a[x]);
				}
				return res.slice(i || 0, j || res.length);
			} : function( a, i, j )
			{
				return Array.prototype.slice.call(a, i || 0, j || a.length);
			};
		}(),

		isIterable: function( v )
		{
			// check for array or arguments
			if( Ext.isArray(v) || v.callee )
			{
				return true;
			}
			// check for node list type
			if( /NodeList|HTMLCollection/.test(toString.call(v)) )
			{
				return true;
			}
			// NodeList has an item and length property
			// IXMLDOMNodeList has nextNode method, needs to be checked first.
			return ((typeof v.nextNode != 'undefined' || v.item) && Ext.isNumber(v.length));
		},

		/**
		 * Iterates an array calling the supplied function.
		 * 
		 * @param {Array/NodeList/Mixed} array The array to be iterated. If this argument is not really an array, the supplied function is called once.
		 * @param {Function} fn The function to be called with each item. If the supplied function returns false, iteration stops and this method returns the
		 *        current <code>index</code>. This function is called with the following arguments: <div class="mdetail-params"><ul> <li><code>item</code> :
		 *        <i>Mixed</i> <div class="sub-desc">The item at the current <code>index</code> in the passed <code>array</code></div></li> <li><code>index</code> :
		 *        <i>Number</i> <div class="sub-desc">The current index within the array</div></li> <li><code>allItems</code> : <i>Array</i> <div
		 *        class="sub-desc">The <code>array</code> passed as the first argument to <code>Ext.each</code>.</div></li> </ul></div>
		 * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to the <code>item</code> at the
		 *        current <code>index</code> within the passed <code>array</code>.
		 * @return See description for the fn parameter.
		 */
		each: function( array, fn, scope )
		{
			if( Ext.isEmpty(array, true) )
			{
				return;
			}
			if( !Ext.isIterable(array) || Ext.isPrimitive(array) )
			{
				array =
				[
					array
				];
			}
			for( var i = 0, len = array.length; i < len; i++ )
			{
				if( fn.call(scope || array[i], array[i], i, array) === false )
				{
					return i;
				};
			}
		},

		/**
		 * Iterates either the elements in an array, or each of the properties in an object. <b>Note</b>: If you are only iterating arrays, it is better to call
		 * {@link #each}.
		 * 
		 * @param {Object/Array} object The object or array to be iterated
		 * @param {Function} fn The function to be called for each iteration. The iteration will stop if the supplied function returns false, or all array elements /
		 *        object properties have been covered. The signature varies depending on the type of object being interated: <div class="mdetail-params"><ul> <li>Arrays :
		 *        <tt>(Object item, Number index, Array allItems)</tt> <div class="sub-desc"> When iterating an array, the supplied function is called with each
		 *        item.</div></li> <li>Objects : <tt>(String key, Object value, Object)</tt> <div class="sub-desc"> When iterating an object, the supplied
		 *        function is called with each key-value pair in the object, and the iterated object</div></li> </ul></div>
		 * @param {Object} scope The scope (<code>this</code> reference) in which the specified function is executed. Defaults to the <code>object</code> being
		 *        iterated.
		 */
		iterate: function( obj, fn, scope )
		{
			if( Ext.isEmpty(obj) )
			{
				return;
			}
			if( Ext.isIterable(obj) )
			{
				Ext.each(obj, fn, scope);
				return;
			}
			else if( typeof obj == 'object' )
			{
				for( var prop in obj )
				{
					if( obj.hasOwnProperty(prop) )
					{
						if( fn.call(scope || obj, prop, obj[prop], obj) === false )
						{
							return;
						};
					}
				}
			}
		},

		/**
		 * Return the dom node for the passed String (id), dom node, or Ext.Element. Optional 'strict' flag is needed for IE since it can return 'name' and 'id'
		 * elements by using getElementById. Here are some examples:
		 * 
		 * <pre><code>
		 * 		// gets dom node based on id
		 * 		var elDom = Ext.getDom('elId');
		 * 		// gets dom node based on the dom node
		 * 		var elDom1 = Ext.getDom(elDom);
		 * 
		 * 		// If we don 't know if we are working with an
		 * 		// Ext.Element or a dom node use Ext.getDom
		 * 		function(el){
		 * 		var dom = Ext.getDom(el);
		 * 		// do something with the dom node
		 * 		}
		 * </code></pre>
		 * 
		 * <b>Note</b>: the dom node to be found actually needs to exist (be rendered, etc) when this method is called to be successful.
		 * 
		 * @param {Mixed} el
		 * @return HTMLElement
		 */

		// strict-->>在IE下是否忽略把name当作ID处理的bug，默认为false，忽略，若设为true，表示不忽略
		getDom: function( el, strict )
		{
			// 如果el不存在，或者document不存在
			if( !el || !DOC )
			{
				return null;
			}
			if( el.dom )
			{
				return el.dom;
			}
			else
			{
				if( typeof el == 'string' )
				{
					var e = DOC.getElementById(el);
					// IE returns elements with the 'name' and 'id' attribute.
					// we do a strict check to return the element with only the id attribute
					// 在IE7以前的版本中，有一个Bug，就是通过getElementById获取节点的时候，IE会把name属性当成id属性来处理。
					// http://younglab.blog.51cto.com/416652/269474
					if( e && isIE && strict )
					{ // 如果是IE，并且el是string，并且strict标志位为true
						if( el == e.getAttribute('id') )
						{
							return e;
						}
						else
						{
							return null;
						}
					}
					return e;
				}
				else
				{ // 如果el不是string，直接return
					return el;
				}
			}
		},

		/**
		 * Returns the current document body as an {@link Ext.Element}.
		 * 
		 * @return Ext.Element The document body
		 */
		getBody: function()
		{
			return Ext.get(DOC.body || DOC.documentElement);
		},

		/**
		 * Returns the current document body as an {@link Ext.Element}.
		 * 
		 * @return Ext.Element The document body
		 * @method
		 */
		getHead: function()
		{
			var head;

			return function()
			{
				if( head == undefined )
				{
					head = Ext.get(DOC.getElementsByTagName("head")[0]);
				}

				return head;
			};
		}(),

		/**
		 * <p>Removes this element from the document, removes all DOM event listeners, and deletes the cache reference. All DOM event listeners are removed from
		 * this element. If {@link Ext#enableNestedListenerRemoval} is <code>true</code>, then DOM event listeners are also removed from all child nodes. The
		 * body node will be ignored if passed in.</p>
		 * 
		 * @param {HTMLElement} node The node to remove
		 * @method
		 */
		removeNode: isIE && !isIE8 ? function()
		{
			var d;
			return function( n )
			{
				if( n && n.tagName != 'BODY' )
				{
					(Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
					d = d || DOC.createElement('div');
					d.appendChild(n);
					d.innerHTML = '';
					delete Ext.elCache[n.id];
				}
			};
		}() : function( n )
		{
			if( n && n.parentNode && n.tagName != 'BODY' )
			{
				(Ext.enableNestedListenerRemoval) ? Ext.EventManager.purgeElement(n, true) : Ext.EventManager.removeAll(n);
				n.parentNode.removeChild(n);
				delete Ext.elCache[n.id];
			}
		},

		/**
		 * <p>Returns true if the passed value is empty.</p> <p>The value is deemed to be empty if it is<div class="mdetail-params"><ul> <li>null</li> <li>undefined</li>
		 * <li>an empty array</li> <li>a zero length string (Unless the <tt>allowBlank</tt> parameter is <tt>true</tt>)</li> </ul></div>
		 * 
		 * @param {Mixed} value The value to test
		 * @param {Boolean} allowBlank (optional) true to allow empty strings (defaults to false)
		 * @return {Boolean}
		 */
		isEmpty: function( v, allowBlank )
		{
			return v === null || v === undefined || ((Ext.isArray(v) && !v.length)) || (!allowBlank ? v === '' : false);
		},

		/**
		 * Returns true if the passed value is a JavaScript array, otherwise false.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isArray: function( v )
		{
			return toString.apply(v) === '[object Array]';
		},

		/**
		 * Returns true if the passed object is a JavaScript date object, otherwise false.
		 * 
		 * @param {Object} object The object to test
		 * @return {Boolean}
		 */
		isDate: function( v )
		{
			return toString.apply(v) === '[object Date]';
		},

		/**
		 * Returns true if the passed value is a JavaScript Object, otherwise false.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isObject: function( v )
		{
			return !!v && Object.prototype.toString.call(v) === '[object Object]';
		},

		/**
		 * Returns true if the passed value is a JavaScript 'primitive', a string, number or boolean.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isPrimitive: function( v )
		{
			return Ext.isString(v) || Ext.isNumber(v) || Ext.isBoolean(v);
		},

		/**
		 * Returns true if the passed value is a JavaScript Function, otherwise false.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isFunction: function( v )
		{
			return toString.apply(v) === '[object Function]';
		},

		/**
		 * Returns true if the passed value is a number. Returns false for non-finite numbers.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isNumber: function( v )
		{
			return typeof v === 'number' && isFinite(v);
		},

		/**
		 * Returns true if the passed value is a string.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isString: function( v )
		{
			return typeof v === 'string';
		},

		/**
		 * Returns true if the passed value is a boolean.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isBoolean: function( v )
		{
			return typeof v === 'boolean';
		},

		/**
		 * Returns true if the passed value is an HTMLElement
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isElement: function( v )
		{
			return v ? !!v.tagName : false;
		},

		/**
		 * Returns true if the passed value is not undefined.
		 * 
		 * @param {Mixed} value The value to test
		 * @return {Boolean}
		 */
		isDefined: function( v )
		{
			return typeof v !== 'undefined';
		},

		/**
		 * True if the detected browser is Opera.
		 * 
		 * @type Boolean
		 */
		isOpera: isOpera,
		/**
		 * True if the detected browser uses WebKit.
		 * 
		 * @type Boolean
		 */
		isWebKit: isWebKit,
		/**
		 * True if the detected browser is Chrome.
		 * 
		 * @type Boolean
		 */
		isChrome: isChrome,
		/**
		 * True if the detected browser is Safari.
		 * 
		 * @type Boolean
		 */
		isSafari: isSafari,
		/**
		 * True if the detected browser is Safari 3.x.
		 * 
		 * @type Boolean
		 */
		isSafari3: isSafari3,
		/**
		 * True if the detected browser is Safari 4.x.
		 * 
		 * @type Boolean
		 */
		isSafari4: isSafari4,
		/**
		 * True if the detected browser is Safari 2.x.
		 * 
		 * @type Boolean
		 */
		isSafari2: isSafari2,
		/**
		 * True if the detected browser is Internet Explorer.
		 * 
		 * @type Boolean
		 */
		isIE: isIE,
		/**
		 * True if the detected browser is Internet Explorer 6.x.
		 * 
		 * @type Boolean
		 */
		isIE6: isIE6,
		/**
		 * True if the detected browser is Internet Explorer 7.x.
		 * 
		 * @type Boolean
		 */
		isIE7: isIE7,
		/**
		 * True if the detected browser is Internet Explorer 8.x.
		 * 
		 * @type Boolean
		 */
		isIE8: isIE8,
		/**
		 * True if the detected browser is Internet Explorer 9.x.
		 * 
		 * @type Boolean
		 */
		isIE9: isIE9,

		/**
		 * True if the detected browser is Internet Explorer 10.x
		 * 
		 * @type Boolean
		 */
		isIE10: isIE10,

		/**
		 * True if the detected browser is Internet Explorer 9.x or lower
		 * 
		 * @type Boolean
		 */
		isIE9m: isIE9m,

		/**
		 * True if the detected browser is Internet Explorer 10.x or higher
		 * 
		 * @type Boolean
		 */
		isIE10p: isIE && !(isIE6 || isIE7 || isIE8 || isIE9),

		// IE10 quirks behaves like Gecko/WebKit quirks, so don't include it here
		// Used internally
		isIEQuirks: isIE && (!isStrict && (isIE6 || isIE7 || isIE8 || isIE9)),

		/**
		 * True if the detected browser uses the Gecko layout engine (e.g. Mozilla, Firefox).
		 * 
		 * @type Boolean
		 */
		isGecko: isGecko,
		/**
		 * True if the detected browser uses a pre-Gecko 1.9 layout engine (e.g. Firefox 2.x).
		 * 
		 * @type Boolean
		 */
		isGecko2: isGecko2,
		/**
		 * True if the detected browser uses a Gecko 1.9+ layout engine (e.g. Firefox 3.x).
		 * 
		 * @type Boolean
		 */
		isGecko3: isGecko3,
		/**
		 * True if the detected browser is Internet Explorer running in non-strict mode.
		 * 
		 * @type Boolean
		 */
		isBorderBox: isBorderBox,
		/**
		 * True if the detected platform is Linux.
		 * 
		 * @type Boolean
		 */
		isLinux: isLinux,
		/**
		 * True if the detected platform is Windows.
		 * 
		 * @type Boolean
		 */
		isWindows: isWindows,
		/**
		 * True if the detected platform is Mac OS.
		 * 
		 * @type Boolean
		 */
		isMac: isMac,
		/**
		 * True if the detected platform is Adobe Air.
		 * 
		 * @type Boolean
		 */
		isAir: isAir
	});

	/**
	 * Creates namespaces to be used for scoping variables and classes so that they are not global. Specifying the last node of a namespace implicitly creates all
	 * other nodes. Usage:
	 * 
	 * <pre><code>
	 * 	Ext.namespace('Company', 'Company.data');
	 * 	Ext.namespace('Company.data'); // equivalent and preferable to above syntax
	 * 	Company.Widget = function() { ... }
	 * 	Company.data.CustomStore = function(config) { ... }
	 * 	
	 * </code></pre>
	 * 
	 * @param {String} namespace1
	 * @param {String} namespace2
	 * @param {String} etc
	 * @return {Object} The namespace object. (If multiple arguments are passed, this will be the last namespace created)
	 * @method ns
	 */
	Ext.ns = Ext.namespace;
})();

Ext.ns('Ext.util', 'Ext.lib', 'Ext.data', 'Ext.supports');

Ext.elCache = {};